コンテナイメージの一貫性を保持するスケジューリングロジックがコンテナ単位で設定可能になりました
こんにちは! AWS 事業本部コンサルティング部のたかくに(@takakuni_)です。
Amazon ECS でコンテナイメージの一貫性を保持するスケジューリングロジックがコンテナ単位で設定可能になりました。
何が嬉しいのか
2024 年 07 月にアップデートがあったアップデートに遡ります。
ざっくり説明すると、ECS のスケジューリングロジックが、次のような挙動に変更されました。
- ECS デプロイメント開始時に、デプロイするコンテナイメージに対するイメージダイジェストの解決
- イメージダイジェストを ECS のコントロールプレーンに保管
- 以降のタスクはコントロールプレーンに保管された情報をもとにタスク起動する
詳しくは以下をご覧ください。
今回のアップデートは、この「イメージダイジェストを解決し、一貫性を保つスケジューリングロジックをコンテナ単位でオプトイン/アウトできるようになりました」というものです。
サードーパーティ製品等で、サイドカーコンテナを組み込んでたりすると、あえて latest
のライフサイクルで追従して欲しいケースもあるため、そういった方向けのアップデートになります。
設定方法
今回、タスク定義の Container definitions 内のパラメーターに新しく versionConsistency
パラメーターが追加されました。
このパラメーターを利用することで、特定コンテナのイメージダイジェストの解決が行われないように設定できます。
Specifies whether Amazon ECS will resolve the container image tag provided in the container definition to an image digest. By default, the value is enabled. If you set the value for a container as disabled, Amazon ECS will not resolve the provided container image tag to a digest and will use the original image URI specified in the container definition for deployment. For more information about container image resolution, see Container image resolution in the Amazon ECS Developer Guide.
Type: String
Valid Values: enabled | disabled
Required: No
Amazon ECS task definition parameters - Amazon Elastic Container Service
やってみた
それでは、今回は versionConsistency
パラメーターを使って、コンテナイメージの統一設定をオフにしてみようと思います。
サードーパーティ製品の latest イメージを書き換えるわけにはいかないため、アプリケーションコンテナに対して versionConsistency
パラメーターを使って挙動を確認してみようと思います。
Nginx コンテナのタスク定義に versionConsistency パラメーターを追加してみます。
{
"family": "nginx-samples",
"containerDefinitions": [
{
+ "versionConsistency": "disabled",
"name": "nginx",
"image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-samples:latest",
"cpu": 0,
"portMappings": [
{
"name": "nginx",
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp",
"appProtocol": "http"
}
],
"essential": true,
"environment": [],
"mountPoints": [],
"volumesFrom": [],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/nginx-samples",
"mode": "non-blocking",
"awslogs-create-group": "true",
"max-buffer-size": "25m",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
},
"systemControls": []
}
],
"taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"networkMode": "awsvpc",
"volumes": [],
"placementConstraints": [],
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"runtimePlatform": {
"cpuArchitecture": "ARM64",
"operatingSystemFamily": "LINUX"
}
}
ECR には v1
タグが latest
に向いている状態とします。イメージダイジェストが sha256:f137d
から始まるコンテナイメージになります。
1 タスクのみ動く ECS サービスを作成し、イメージダイジェストを確認すると、sha256:f137d
から始まるコンテナイメージでコンテナが起動していることがわかりますね。
[cloudshell-user@ip-10-130-40-229 ~]$ TASK_ARNS=$(aws ecs list-tasks --cluster ecs --query taskArns --output text)
[cloudshell-user@ip-10-130-40-229 ~]$ aws ecs describe-tasks --cluster ecs --tasks $TASK_ARNS --no-cli-pager
{
"tasks": [
{
"attachments": [
{
"id": "77b389a6-e40d-4dc4-9356-cf3b50bbd007",
"type": "ElasticNetworkInterface",
"status": "ATTACHED",
"details": [
{
"name": "subnetId",
"value": "subnet-0deef2f54bbb1a19b"
},
{
"name": "networkInterfaceId",
"value": "eni-003ae4a6ec673a682"
},
{
"name": "macAddress",
"value": "0e:42:e2:0b:72:f9"
},
{
"name": "privateDnsName",
"value": "ip-172-31-20-140.ap-northeast-1.compute.internal"
},
{
"name": "privateIPv4Address",
"value": "172.31.20.140"
}
]
}
],
"attributes": [
{
"name": "ecs.cpu-architecture",
"value": "arm64"
}
],
"availabilityZone": "ap-northeast-1d",
"clusterArn": "arn:aws:ecs:ap-northeast-1:123456789012:cluster/ecs",
"connectivity": "CONNECTED",
"connectivityAt": "2024-11-22T14:22:43.772000+00:00",
"containers": [
{
"containerArn": "arn:aws:ecs:ap-northeast-1:123456789012:container/ecs/95571b976e5f4668b68568f6174d27de/c2370c63-f6b2-44c0-8fd5-0e0aca98aede",
"taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/ecs/95571b976e5f4668b68568f6174d27de",
"name": "nginx",
"image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-samples",
+ "imageDigest": "sha256:f137d1b066c8010b5dcea233398ed4c114209c73bde0a121137ea148660affec",
"runtimeId": "95571b976e5f4668b68568f6174d27de-2531612879",
"lastStatus": "RUNNING",
"networkBindings": [],
"networkInterfaces": [
{
"attachmentId": "77b389a6-e40d-4dc4-9356-cf3b50bbd007",
"privateIpv4Address": "172.31.20.140"
}
],
"healthStatus": "UNKNOWN",
"cpu": "0"
}
],
"cpu": "512",
"createdAt": "2024-11-22T14:22:40.229000+00:00",
"desiredStatus": "RUNNING",
"enableExecuteCommand": false,
"group": "service:ecs",
"healthStatus": "UNKNOWN",
"lastStatus": "RUNNING",
"launchType": "FARGATE",
"memory": "1024",
"overrides": {
"containerOverrides": [
{
"name": "nginx"
}
],
"inferenceAcceleratorOverrides": []
},
"platformVersion": "1.4.0",
"platformFamily": "Linux",
"pullStartedAt": "2024-11-22T14:22:50.378000+00:00",
"pullStoppedAt": "2024-11-22T14:22:57.667000+00:00",
"startedAt": "2024-11-22T14:22:58.178000+00:00",
"startedBy": "ecs-svc/0053364041503124110",
"tags": [],
"taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/ecs/95571b976e5f4668b68568f6174d27de",
"taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/nginx-samples:3",
"version": 5,
"ephemeralStorage": {
"sizeInGiB": 20
},
"fargateEphemeralStorage": {
"sizeInGiB": 20
}
}
],
"failures": []
}
続いて、 v2
タグが latest
に向いている状態に変更します。イメージダイジェストが sha256:696e6
から始まるコンテナイメージになります。
同じタスク定義で ECS サービスのタスク数を 1 から 3 に変更してみました。(スケールアウトを想定)
起動開始時間から ECS タスクが 2 つ増えていることがわかります。
再度、 describe-tasks
コマンドを実行すると、追加で起動した ECS タスクは、初回のコンテナとは別のイメージダイジェストで起動していますね。デフォルトで動作していたイメージダイジェストの解決および、一貫性の保持をオプトアウトできていることがわかります。
[cloudshell-user@ip-10-130-40-229 ~]$ TASK_ARNS=$(aws ecs list-tasks --cluster ecs --query taskArns --output text)
[cloudshell-user@ip-10-130-40-229 ~]$ aws ecs describe-tasks --cluster ecs --tasks $TASK_ARNS --no-cli-pager
{
"tasks": [
{
"attachments": [
{
"id": "77b389a6-e40d-4dc4-9356-cf3b50bbd007",
"type": "ElasticNetworkInterface",
"status": "ATTACHED",
"details": [
{
"name": "subnetId",
"value": "subnet-0deef2f54bbb1a19b"
},
{
"name": "networkInterfaceId",
"value": "eni-003ae4a6ec673a682"
},
{
"name": "macAddress",
"value": "0e:42:e2:0b:72:f9"
},
{
"name": "privateDnsName",
"value": "ip-172-31-20-140.ap-northeast-1.compute.internal"
},
{
"name": "privateIPv4Address",
"value": "172.31.20.140"
}
]
}
],
"attributes": [
{
"name": "ecs.cpu-architecture",
"value": "arm64"
}
],
"availabilityZone": "ap-northeast-1d",
"clusterArn": "arn:aws:ecs:ap-northeast-1:123456789012:cluster/ecs",
"connectivity": "CONNECTED",
"connectivityAt": "2024-11-22T14:22:43.772000+00:00",
"containers": [
{
"containerArn": "arn:aws:ecs:ap-northeast-1:123456789012:container/ecs/95571b976e5f4668b68568f6174d27de/c2370c63-f6b2-44c0-8fd5-0e0aca98aede",
"taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/ecs/95571b976e5f4668b68568f6174d27de",
"name": "nginx",
"image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-samples",
+ "imageDigest": "sha256:f137d1b066c8010b5dcea233398ed4c114209c73bde0a121137ea148660affec",
"runtimeId": "95571b976e5f4668b68568f6174d27de-2531612879",
"lastStatus": "RUNNING",
"networkBindings": [],
"networkInterfaces": [
{
"attachmentId": "77b389a6-e40d-4dc4-9356-cf3b50bbd007",
"privateIpv4Address": "172.31.20.140"
}
],
"healthStatus": "UNKNOWN",
"cpu": "0"
}
],
"cpu": "512",
"createdAt": "2024-11-22T14:22:40.229000+00:00",
"desiredStatus": "RUNNING",
"enableExecuteCommand": false,
"group": "service:ecs",
"healthStatus": "UNKNOWN",
"lastStatus": "RUNNING",
"launchType": "FARGATE",
"memory": "1024",
"overrides": {
"containerOverrides": [
{
"name": "nginx"
}
],
"inferenceAcceleratorOverrides": []
},
"platformVersion": "1.4.0",
"platformFamily": "Linux",
"pullStartedAt": "2024-11-22T14:22:50.378000+00:00",
"pullStoppedAt": "2024-11-22T14:22:57.667000+00:00",
"startedAt": "2024-11-22T14:22:58.178000+00:00",
"startedBy": "ecs-svc/0053364041503124110",
"tags": [],
"taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/ecs/95571b976e5f4668b68568f6174d27de",
"taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/nginx-samples:3",
"version": 5,
"ephemeralStorage": {
"sizeInGiB": 20
},
"fargateEphemeralStorage": {
"sizeInGiB": 20
}
},
{
"attachments": [
{
"id": "abcbe09f-d87a-4089-b742-709379342eeb",
"type": "ElasticNetworkInterface",
"status": "ATTACHED",
"details": [
{
"name": "subnetId",
"value": "subnet-05a65d661b1a74795"
},
{
"name": "networkInterfaceId",
"value": "eni-0a3e08bc8d882153c"
},
{
"name": "macAddress",
"value": "06:8d:a3:0e:b6:5b"
},
{
"name": "privateDnsName",
"value": "ip-172-31-34-45.ap-northeast-1.compute.internal"
},
{
"name": "privateIPv4Address",
"value": "172.31.34.45"
}
]
}
],
"attributes": [
{
"name": "ecs.cpu-architecture",
"value": "arm64"
}
],
"availabilityZone": "ap-northeast-1a",
"clusterArn": "arn:aws:ecs:ap-northeast-1:123456789012:cluster/ecs",
"connectivity": "CONNECTED",
"connectivityAt": "2024-11-22T14:37:26.699000+00:00",
"containers": [
{
"containerArn": "arn:aws:ecs:ap-northeast-1:123456789012:container/ecs/e12a180bbcb645d792cd61a69c89d12c/2e61a1d3-935b-4f12-8a4a-d625c0182ab7",
"taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/ecs/e12a180bbcb645d792cd61a69c89d12c",
"name": "nginx",
"image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-samples",
+ "imageDigest": "sha256:696e6a7ecc4ccf595af5aec8e395967fbca01d214ec79a9ee536de56a0135c85",
"runtimeId": "e12a180bbcb645d792cd61a69c89d12c-2531612879",
"lastStatus": "RUNNING",
"networkBindings": [],
"networkInterfaces": [
{
"attachmentId": "abcbe09f-d87a-4089-b742-709379342eeb",
"privateIpv4Address": "172.31.34.45"
}
],
"healthStatus": "UNKNOWN",
"cpu": "0"
}
],
"cpu": "512",
"createdAt": "2024-11-22T14:37:22.096000+00:00",
"desiredStatus": "RUNNING",
"enableExecuteCommand": false,
"group": "service:ecs",
"healthStatus": "UNKNOWN",
"lastStatus": "RUNNING",
"launchType": "FARGATE",
"memory": "1024",
"overrides": {
"containerOverrides": [
{
"name": "nginx"
}
],
"inferenceAcceleratorOverrides": []
},
"platformVersion": "1.4.0",
"platformFamily": "Linux",
"pullStartedAt": "2024-11-22T14:37:35.459000+00:00",
"pullStoppedAt": "2024-11-22T14:37:38.643000+00:00",
"startedAt": "2024-11-22T14:37:38.610000+00:00",
"startedBy": "ecs-svc/0053364041503124110",
"tags": [],
"taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/ecs/e12a180bbcb645d792cd61a69c89d12c",
"taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/nginx-samples:3",
"version": 4,
"ephemeralStorage": {
"sizeInGiB": 20
},
"fargateEphemeralStorage": {
"sizeInGiB": 20
}
},
{
"attachments": [
{
"id": "7064bf4c-c15c-499a-bb03-f2034f674c77",
"type": "ElasticNetworkInterface",
"status": "ATTACHED",
"details": [
{
"name": "subnetId",
"value": "subnet-0f5238f9112b400e1"
},
{
"name": "networkInterfaceId",
"value": "eni-026d29e3a0d73dc55"
},
{
"name": "macAddress",
"value": "0a:71:72:38:82:bd"
},
{
"name": "privateDnsName",
"value": "ip-172-31-6-205.ap-northeast-1.compute.internal"
},
{
"name": "privateIPv4Address",
"value": "172.31.6.205"
}
]
}
],
"attributes": [
{
"name": "ecs.cpu-architecture",
"value": "arm64"
}
],
"availabilityZone": "ap-northeast-1c",
"clusterArn": "arn:aws:ecs:ap-northeast-1:123456789012:cluster/ecs",
"connectivity": "CONNECTED",
"connectivityAt": "2024-11-22T14:37:26.734000+00:00",
"containers": [
{
"containerArn": "arn:aws:ecs:ap-northeast-1:123456789012:container/ecs/e55eaaf1c9594c56bc9baf88f71e754e/d7a0e7eb-bbe9-4d36-a5f9-c252a667e0e1",
"taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/ecs/e55eaaf1c9594c56bc9baf88f71e754e",
"name": "nginx",
"image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-samples",
+ "imageDigest": "sha256:696e6a7ecc4ccf595af5aec8e395967fbca01d214ec79a9ee536de56a0135c85",
"runtimeId": "e55eaaf1c9594c56bc9baf88f71e754e-2531612879",
"lastStatus": "RUNNING",
"networkBindings": [],
"networkInterfaces": [
{
"attachmentId": "7064bf4c-c15c-499a-bb03-f2034f674c77",
"privateIpv4Address": "172.31.6.205"
}
],
"healthStatus": "UNKNOWN",
"cpu": "0"
}
],
"cpu": "512",
"createdAt": "2024-11-22T14:37:22.096000+00:00",
"desiredStatus": "RUNNING",
"enableExecuteCommand": false,
"group": "service:ecs",
"healthStatus": "UNKNOWN",
"lastStatus": "RUNNING",
"launchType": "FARGATE",
"memory": "1024",
"overrides": {
"containerOverrides": [
{
"name": "nginx"
}
],
"inferenceAcceleratorOverrides": []
},
"platformVersion": "1.4.0",
"platformFamily": "Linux",
"pullStartedAt": "2024-11-22T14:37:34.938000+00:00",
"pullStoppedAt": "2024-11-22T14:37:38.130000+00:00",
"startedAt": "2024-11-22T14:37:38.383000+00:00",
"startedBy": "ecs-svc/0053364041503124110",
"tags": [],
"taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/ecs/e55eaaf1c9594c56bc9baf88f71e754e",
"taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/nginx-samples:3",
"version": 4,
"ephemeralStorage": {
"sizeInGiB": 20
},
"fargateEphemeralStorage": {
"sizeInGiB": 20
}
}
],
"failures": []
}
まとめ
以上、「Amazon ECS でコンテナイメージの一貫性を保持するスケジューリングロジックがコンテナ単位で設定可能になりました。」でした。
サイドカーコンテナのように latest
タグを使って追従し続けたいようなケースにおいては、有効な手段の 1 つになりそうです。このブログがどなたかの参考になれば幸いです。
AWS 事業本部コンサルティング部のたかくに(@takakuni_)でした!